package com.atguigu.gmall.item.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.item.service.ItemService;
import com.atguigu.gmall.list.client.ListFeignClient;
import com.atguigu.gmall.model.product.BaseCategoryView;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.model.product.SpuSaleAttr;
import com.atguigu.gmall.product.client.ProductFeignClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author Fxz
 * @version 1.0
 * @date 2022-02-07 16:58
 */
@SuppressWarnings("all")
@Slf4j
@Service
@RequiredArgsConstructor
public class ItemServiceImpl implements ItemService {

	private final ListFeignClient listFeignClient;

	private final ProductFeignClient productFeignClient;

	private final ThreadPoolExecutor threadPoolExecutor;

	/**
	 * 异步编排 跟据skuId获取sku信息
	 */
	@Override
	public Map<String, Object> getItemBySkuId(Long skuId) {
		Map<String, Object> result = new HashMap<>();
		AtomicReference<SkuInfo> skuInfo = new AtomicReference<>(new SkuInfo());
		AtomicReference<BigDecimal> skuPrice = new AtomicReference<>(BigDecimal.ZERO);
		AtomicReference<BaseCategoryView> categoryView = new AtomicReference<>(new BaseCategoryView());
		AtomicReference<List<SpuSaleAttr>> spuSaleAttrListCheckBySku = new AtomicReference<>(new LinkedList<>());
		AtomicReference<Map> skuValueIdsMap = new AtomicReference<>(new HashMap<>(1));

		// 异步编排 获取skuInfo和skuImageList
		CompletableFuture<SkuInfo> skuInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
			skuInfo.set(productFeignClient.getSkuInfo(skuId));
			return skuInfo.get();
		}, threadPoolExecutor);

		// 跟据skuInfo的三级分类id查询分类信息
		CompletableFuture<Void> categoryViewCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(sku -> {
			Optional.ofNullable(sku)
					.ifPresent(item -> categoryView.set(productFeignClient.getCategoryView(item.getCategory3Id())));
		}, threadPoolExecutor);

		// 获取销售属性+销售属性值
		CompletableFuture<Void> spuSaleAttrListCheckBySkuCompletableFuture = skuInfoCompletableFuture
				.thenAcceptAsync(sku -> {
					Optional.ofNullable(sku).ifPresent(item -> spuSaleAttrListCheckBySku
							.set(productFeignClient.getSpuSaleAttrListCheckBySku(item.getId(), item.getSpuId())));
				}, threadPoolExecutor);

		// 查询销售属性值id与skuId组合的map
		CompletableFuture<Void> skuValueIdsMapCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(sku -> {
			Optional.ofNullable(sku)
					.ifPresent(item -> skuValueIdsMap.set(productFeignClient.getSkuValueIdsMap(item.getSpuId())));
		}, threadPoolExecutor);

		// 获取价格
		CompletableFuture<Void> skuPriceCompletableFuture = CompletableFuture
				.runAsync(() -> skuPrice.set(productFeignClient.getSkuPrice(skuId)), threadPoolExecutor);

		// 更新商品热度
		CompletableFuture<Void> incrHotScoreCompletableFuture = CompletableFuture.runAsync(() -> {
			Result score = listFeignClient.incrHotScore(skuId);
			log.info("更新商品:{} 热度:{}", skuId, score);
		}, threadPoolExecutor);

		// 多任务组合
		CompletableFuture.allOf(skuInfoCompletableFuture, categoryViewCompletableFuture,
				spuSaleAttrListCheckBySkuCompletableFuture, skuValueIdsMapCompletableFuture, skuPriceCompletableFuture,
				incrHotScoreCompletableFuture).join();

		result.put("skuInfo", skuInfo);
		result.put("price", skuPrice.get());
		result.put("categoryView", categoryView);
		result.put("spuSaleAttrList", spuSaleAttrListCheckBySku);
		result.put("valuesSkuJson", JSON.toJSONString(skuValueIdsMap.get()));

		return result;
	}

}
